from web3 import Web3, HTTPProvider
from web3.eth import Eth
from web3.contract import ConciseContract
import web3
from eth_account import Account
from eth_account.local import LocalAccount
from eth_keys import keys
from hexbytes import HexBytes
import json
import common 
import base64
import solc
from binascii import b2a_hex, a2b_hex
from db import DBHelper
from common.strtools import hex_add_0x,hex_remove_0x

from myeth_env import w3
from myeth import MyContract,MyAccountHelper

class MyWeb3DO:
    def __init__(self, acctDO, contDO):
        self.account_DO = acctDO
        self.contract_DO = contDO

    def defaultAccount(self):
        w3.eth.defaultAccount = self.account_DO.address

    def addUser(self, add_address)->bool: # 返回值为true代表添加成功，返回值为false代表添加失败 TODO DO调用
        self.defaultAccount()
        flag = self.contract_DO.functions.addUser(add_address).transact()
        return flag

    def removeUser(self, rm_address)->bool: # 返回值为false代表移除成功，返回值为true代表移除失败 TODO DO调用
        self.defaultAccount()
        flag = self.contract_DO.functions.removeUser(rm_address).transact()
        return flag

    def addIndex(self, Indexkeyword:list, transaction_id:bytes, filename:str)->bool: # TODO DO调用
        self.defaultAccount()
        Indexkeyword_bytes = []
        for bytes_data in Indexkeyword:
            if len(bytes_data)!=32:
                print("输入无效的关键字索引")
                return False
            else:
                Indexkeyword_bytes.append(bytes(bytes_data, encoding="utf8"))

        if len(transaction_id) != 32:
            print("输入无效的交易id")
            return False
        hex_array = [Web3.toHex(bytes_data) for bytes_data in Indexkeyword_bytes] 
        self.contract_DO.functions.addIndex(hex_array, transaction_id, filename).transact()
        return True

    def deleteIndex(self, Indexkeyword)->bool: # TODO DO调用
        self.defaultAccount()
        Indexkeyword_bytes = []
        for bytes_data in Indexkeyword:
            if len(bytes_data)!=32:
                print("输入无效的关键字索引")
                return False   
            else:
                Indexkeyword_bytes.append(bytes(bytes_data, encoding="utf8"))
        hex_array = [Web3.toHex(bytes_data) for bytes_data in Indexkeyword_bytes] 
        self.contract_DO.functions.deleteIndex(hex_array).transact()
        return True

    def getFilenames(self)->list: # TODO DO调用
        self.defaultAccount()
        filenames_list = (self.contract_DO.functions.getFilenames().call()).split('*')
        filenames_list.pop()
        return filenames_list

    def search(self, Indexkeyword)->list: # TODO DO调用
        self.defaultAccount()
        txids = []
        Indexkeyword_bytes = []
        for bytes_data in Indexkeyword:
            if len(bytes_data) != 32:
                print("输入无效的关键字索引")
                return txids
            else:
                Indexkeyword_bytes.append(bytes(bytes_data, encoding="utf8"))
        hex_array = [Web3.toHex(bytes_data) for bytes_data in Indexkeyword_bytes] 
        tranids = self.contract_DO.functions.search(hex_array).call()
        tranids_str = str(tranids,'utf-8')
        l = int(len(tranids_str)/32)
        for i in range(l):
            txids.append(tranids_str[i*32:i*32+32])
        return list(set(txids))

class MyWeb3DU:
    def __init__(self, acctDU, contDU):
        self.account_DU = acctDU
        self.contract_DU = contDU

    def defaultAccount(self):
        w3.eth.defaultAccount = self.account_DU.address
        
    def dataSearch(self, Indexkeyword, address_DO_contract)->bool:  # TODO DU调用
        self.defaultAccount()
        Indexkeyword_bytes = []
        for bytes_data in Indexkeyword:
            if len(bytes_data) != 32:
                print("输入无效的关键字索引")
                return False
            else:
                Indexkeyword_bytes.append(bytes(bytes_data, encoding="utf8"))
        hex_array = [Web3.toHex(bytes_data) for bytes_data in Indexkeyword_bytes] 
        self.contract_DU.functions.dataSearch(hex_array, address_DO_contract).transact()
        return True

    def getResult(self, address_DO_contract)->list:  # TODO DU调用
        self.defaultAccount()
        txids = []
        tranids = self.contract_DU.functions.getResult(address_DO_contract).call()
        # tranids_str = str(tranids, 'utf-8')
        # tranids_str = hex_add_0x(b2a_hex(tranids).decode("utf-8"))
        l = int(len(tranids)/32)
        for i in range(l):
            txid = tranids[i*32:i*32+32]
            txid = hex_add_0x(b2a_hex(txid).decode("utf-8"))
            txids.append(txid)
        return list(set(txids))

# if __name__ =="__main__":
#     #DO部署智能合约
#     DOContract = MyContract.from_src_file(common.args.contractFile,True) # True代表DO，False DU
#     pkDO = "79574ef0db279e148f37fd65841365827a0a708f31eb925fa2a7029e82be2a6e"
#     acctDO = MyAccountHelper.get_account_from_private_key(pkDO)
#     ccDO = DOContract.deploy_contract(acctDO)    
#     contract_instance_DO = w3.eth.contract(address=ccDO.address, abi=ccDO.abi)
#     # DU部署智能合约
#     UserContract = MyContract.from_src_file(common.args.contractFile,False) # True代表DO，False DU
#     pkUser = "b3073deb364708a94af62f36bc9243273811477892a753fc03e91595d2c8cdcd"
#     acctUser = MyAccountHelper.get_account_from_private_key(pkUser)
#     ccUser = UserContract.deploy_contract(acctUser)
#     contract_instance_User = w3.eth.contract(address=ccUser.address, abi=ccUser.abi)

#     myweb3=MyWeb3(acctDO, acctUser, contract_instance_DO, contract_instance_User)
#     myweb3.defaultAccount(True)  # 设置默认用户为DO
#     if myweb3.addUser(acctUser.address):
#         print("添加用户成功")
#     else:
#         print("添加用户失败")
#     keywordIndex = ["abcdefghijklmnopqrstuvwxyzabcdef","ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEF"]
#     txid = bytes("12222222222222222222222222222221", encoding="utf8")
#     filename = "haaaaaaaah"
#     if myweb3.addIndex(keywordIndex, txid, filename):
#         print("添加keywordIndex filename成功")
#     else:
#         print("添加keywordIndex filename失败")

#     print(myweb3.search(keywordIndex))
#     print(myweb3.getFilenames())

#     myweb3.defaultAccount(False) # 设置默认用户为DU
#     if myweb3.dataSearch(keywordIndex,ccDO.address):
#         print("DU获取文件成功，并保存到智能合约状态变量中")
#     else:
#         print("DU获取文件失败")
#     print(myweb3.getResult(ccDO.address))
# if __name__=="__main__":

    # DO部署智能合约
    # DOContract = MyContract.from_src_file(common.args.contractFile,True) # True代表DO，False DU
    # pkDO = "79574ef0db279e148f37fd65841365827a0a708f31eb925fa2a7029e82be2a6e"
    # acctDO = MyAccountHelper.get_account_from_private_key(pkDO)
    # ccDO = DOContract.deploy_contract(acctDO)


    # #contract_instance_DO = w3.eth.contract(address=ccDO.address, abi=ccDO.abi, ContractFactoryClass=ConciseContract)
    # contract_instance_DO = w3.eth.contract(address=ccDO.address, abi=ccDO.abi)
    
    # print("11111111111111111111111")
    
    # UserContract = MyContract.from_src_file(common.args.contractFile,False) # True代表DO，False DU
    # pkUser = "b3073deb364708a94af62f36bc9243273811477892a753fc03e91595d2c8cdcd"
    # acctUser = MyAccountHelper.get_account_from_private_key(pkUser)
    # ccUser = UserContract.deploy_contract(acctUser)
    # contract_instance_User = w3.eth.contract(address=ccUser.address, abi=ccUser.abi)

    # w3.eth.defaultAccount = acctDO.address  # 设置调用智能合约的默认账户为DO

    # print("222222222222222222222222")
    # if contract_instance_DO.functions.addUser(acctUser.address).transact():
    #     print("添加用户成功")
    # else:
    #     print("添加用户失败")
    # contract_instance_DO.functions.addUser(ccUser.address).transact()

    # Indexkeyword = [bytes("12345678123456781234567812345678", encoding="utf8"),bytes("12345678123456781234567812345678", encoding="utf8")]
    # txid = bytes("abcdefghijklmnopqrstuvwxyzabcdef", encoding="utf8")
    # key1 = bytes("abcdefghabcdefghabcdefghabcdefgh", encoding="utf8")
    # hex_array = [Web3.toHex(bytes_data) for bytes_data in Indexkeyword] 
    # contract_instance_DO.functions.addIndex(hex_array, txid).transact()
    
    # print(contract_instance_DO.functions.search(hex_array).call())
    
    # w3.eth.defaultAccount = acctUser.address # 设置调用智能合约的默认账户为DU

    # contract_instance_User.functions.dataSearch(hex_array, ccDO.address).transact()
    # print(contract_instance_User.functions.getResult(ccDO.address).call())    
    # print(contract_instance_User.functions.gettest(hex_array,ccDO.address).call())
    # print("ccDO  ",ccDO.address)
    # print("ccUser  ",ccUser.address)
    # print("acctDO  ",acctDO.address)
    # print("acctUser  ",acctUser.address)
    # print("tx.origin  ",contract_instance_User.functions.ugetorigin(ccDO.address).call())
    # print("msg.sender  ",contract_instance_User.functions.ugetsender(ccDO.address).call())
    # print("msg.senderbool  ",contract_instance_User.functions.ugetsenderbool(ccDO.address).call())
    # print(contract_instance_User.functions.getResult(ccDO.address).call())

